/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import clases.Persona;
import clases.Revision;
import clases.Rol;
import clases.Seccion;
import clases.Usuario;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Query;
import org.hibernate.Session;
import utilidades.GenerarCadenaAlfanumerica;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Rafa
 */
public class DAO_Usuario {

    Session sesion = null;

    public DAO_Usuario() {
        this.sesion = HibernateUtil.getSessionFactory().getCurrentSession();
    }

    public List<Usuario> consultaUsuarios(boolean iniciar) {
        List<Usuario> listaUsuarios = new ArrayList();
        try {
            if (iniciar) {
                sesion.beginTransaction();
            }
            //sesion.getSessionFactory().getCurrentSession().beginTransaction();

            //Se realiza la consulta
            Query q = sesion.createQuery("from Usuario");

            //Se recoge el resultado de la consulta
            listaUsuarios = (List<Usuario>) q.list();
        } catch (Exception e) {
            e.printStackTrace();

        }

        return listaUsuarios;
    }

    public Usuario consultaUsuario(String user, boolean iniciar) {
        Usuario usuario = null;
        try {
            if (iniciar) {
                sesion.beginTransaction();
            }
            //sesion.getSessionFactory().getCurrentSession().beginTransaction();

            //Se hace la consulta
            Query query = sesion.createQuery("from Usuario where user = '" + user + "'");
        //query.setParameter("user", user);

            //Se recoge el resultado de la consulta
            usuario = (Usuario) query.uniqueResult();
        } catch (Exception e) {
            e.printStackTrace();

        }

        return usuario;
    }

    public Usuario consultaUsuarioPorId(String idUser, boolean iniciar) {
        Usuario usuario = null;
        try {
            if (iniciar) {
                sesion.beginTransaction();
            }
            //sesion.getSessionFactory().getCurrentSession().beginTransaction();
            //Se hace la consulta
            Query query = sesion.createQuery("from Usuario where idUsuario = '" + idUser + "'");

            //Se recoge el resultado de la consulta
            usuario = (Usuario) query.uniqueResult();
        } catch (Exception e) {
            e.printStackTrace();

        }

        return usuario;
    }

    //Se retorna el usuario para poder enviar un correo al usuario con sus datos
    //Los dos pellidos son obligatorios
    public Usuario insertaUsuario(String descripcionPersona, String nombre, String apellidos, String email, boolean iniciar) {
        String user = "";
        String[] noum = nombre.split(" ");
        String[] subname = apellidos.split(" ");

        String subnom;
        String subape1;
        String subape2;

        //Si solo tiene un nombre
        if (noum.length == 1) {
            subnom = noum[0].substring(0, 1); //Se coge la primera letra del nombre
            subape1 = subname[0].substring(0, 4);//Se cogen las 3 primeras letras del apellido1
            subape2 = subname[1].substring(0, 4);//Se cogen las 3 primeras letras del apellido2

            user = subnom + subape1 + subape2;
            user = user.toLowerCase();
        } else if (noum.length > 1) {
            subnom = noum[0].substring(0, 1); //Se coge la primera letra del nombre1
            String subnom2 = noum[1].substring(0, 1); //Se coge la primera letra del nombre2
            subape1 = subname[0].substring(0, 4);//Se cogen las 3 primeras letras del apellido1
            subape2 = subname[1].substring(0, 4);//Se cogen las 3 primeras letras del apellido2

            user = subnom + subnom2 + subape1 + subape2;
            user = user.toLowerCase();
        }
        if (iniciar) {
            sesion.beginTransaction();

            //Si el user ya existe se le anade un caracter más
            if (consultaUsuario(user, false) != null) {
                user += "I";
            }
        }else{
          //Si el user ya existe se le anade un caracter más
            if (consultaUsuario(user, true) != null) {
                user += "I";
            }  
        }
            //sesion.getSessionFactory().getCurrentSession().beginTransaction();

        Usuario usuario = null;
        try {
            sesion.getSessionFactory().getCurrentSession().beginTransaction();

            //Se crea la persona que tendra asociada el usuario
            DAO_Persona daoPersona = new DAO_Persona();
            Persona persona = daoPersona.insertaPersona(nombre, apellidos, email, descripcionPersona, true);

            //Se calcula la fecha de hoy
            java.util.Date utilDate = new java.util.Date();
            java.sql.Date fechaInicio = new java.sql.Date(utilDate.getTime());

            //Se crea la contraseña de 8 caracteres alfanumericos automaticamente 
            String pass = GenerarCadenaAlfanumerica.getCadena(8);

            //Se crea el usuario: (Persona persona, String clave, String user, Date fechaInicio, boolean certificado)
            usuario = new Usuario(persona, pass, user, fechaInicio, false);

            sesion.save(usuario);
            sesion.getTransaction().commit();
        } catch (Exception e) {
            if (sesion.getTransaction() != null) {
                sesion.getTransaction().rollback();
            }
            e.printStackTrace();

        }

        return usuario;
    }

    public boolean eliminaUsuario(String idUser, boolean iniciar) {
        boolean correcto = false;
        try {
            //sesion.getSessionFactory().getCurrentSession().beginTransaction();
            if (iniciar) {
                sesion.beginTransaction();
                sesion.delete(consultaUsuarioPorId(idUser, false));
            } else {
                sesion.delete(consultaUsuarioPorId(idUser, true));
            }

            sesion.getTransaction().commit();
            correcto = true;
        } catch (Exception e) {
            if (sesion.getTransaction() != null) {
                sesion.getTransaction().rollback();
            }
            e.printStackTrace();

        }
        return correcto;
    }

    public boolean modificarUsuario(String idUser, String descUsuario, String nombre, String apellidos, String email, boolean iniciar) {
        boolean correcto = false;
        try {
            Usuario usuario = null;
            //sesion.getSessionFactory().getCurrentSession().beginTransaction();
            if (iniciar) {
                sesion.beginTransaction();
                usuario = consultaUsuarioPorId(idUser, false);
            } else {
                usuario = consultaUsuarioPorId(idUser, true);
            }

            if (usuario != null) {
                usuario.getPersona().setNombre(nombre);
                usuario.getPersona().setApellidos(apellidos);
                usuario.getPersona().setEmail(email);
                usuario.getPersona().setDescripcion(descUsuario);

                sesion.saveOrUpdate(usuario);
                sesion.getTransaction().commit();

                correcto = true;
            }
        } catch (Exception e) {
            if (sesion.getTransaction() != null) {
                sesion.getTransaction().rollback();
            }
            e.printStackTrace();
        }

        return correcto;
    }

    /**
     * Metodo para anadir un rol a un usuario
     *
     * @param usuario
     * @param cadRol
     * @return Usuario
     */
    public Usuario anadirRolUsuario(Usuario usuario, String cadRol, boolean iniciar) {
        DAO_Rol daoRol = new DAO_Rol();
        Rol rol = daoRol.consultaRol(cadRol, true);
        /*Puede ser que el usuario tenga ya algun rol, por lo que
         consultamos sus roles*/
        Set<Rol> rolesUsuario;
        if (usuario.getRols().size() > 0) {
            if (compruebaRolesUsuario(usuario, rol) == false) {
                rolesUsuario = usuario.getRols();
                rolesUsuario.add(rol);
            } else {
                rolesUsuario = usuario.getRols();
            }
        } else {
            rolesUsuario = new HashSet<>();
            rolesUsuario.add(rol);
        }
        usuario.setRols(rolesUsuario);
        if (iniciar) {
            sesion.beginTransaction();
        }
        try {
            sesion.saveOrUpdate(usuario);
            sesion.getTransaction().commit();

        } catch (Exception e) {
            if (sesion.getTransaction() != null) {
                sesion.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return usuario;
    }

    /**
     * Metodo para comprobar si el usuario ya tiene ese rol
     *
     * @param usuario
     * @param rol
     * @return
     */
    public boolean compruebaRolesUsuario(Usuario usuario, Rol rol) {
        boolean tiene = false;
        /*Se coge el conjunto de usuarios de la seccion y luego se pasa a un array*/

        Rol[] roles = usuario.getRols().toArray(new Rol[]{});

        for (int k = 0; k < roles.length; k++) {
            if (roles[k].getIdRol().equals(rol.getIdRol())) {
                tiene = true;
            }
        }
        return tiene;
    }

    public boolean compruebaEmail(String email) {
        // Compiles the given regular expression into a pattern.
        Pattern pattern = Pattern.compile(Constantes.getPATTERN_EMAIL());

        // Match the given input against this pattern
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }
}
